In [102]:
import pandas as pd
import numpy as np
import yfinance as yf
import random
from matplotlib import pyplot as plt
import seaborn as sns
import warnings
import secrets
import plotly as plotly
import plotly.express as px
from tqdm import tqdm
import plotly.graph_objects as go
pd.set_option('plotting.backend', 'matplotlib')
plotly.offline.init_notebook_mode()
#warnings.simplefilter(action='ignore', category=FutureWarnin
import plotly.io as pio
plotly_template = pio.templates["plotly_dark"]
plt.style.use('dark_background')
PORTFOLIO ONLY IWDA
In [103]:
TICKER="IWDA.AS"
NUMBER_OF_SIMULATIONS=1000
STARTING_CAPITAL = 10000
YEARS_OF_SIMULATION=100
In [104]:
YEARS_OF_SIMULATION=YEARS_OF_SIMULATION+1
Market_Days=253
df=yf.download(TICKER)["Adj Close"].pct_change(1).dropna()
[*********************100%%**********************] 1 of 1 completed
In [105]:
df.plot()
Out[105]:
<Axes: xlabel='Date'>
In [106]:
df
Out[106]:
Date
2009-09-28 0.000000
2009-09-29 0.000000
2009-09-30 0.000000
2009-10-01 0.000000
2009-10-02 0.000000
...
2023-11-20 0.000894
2023-11-21 0.000447
2023-11-22 0.008357
2023-11-23 -0.000506
2023-11-24 -0.001899
Name: Adj Close, Length: 3629, dtype: float64
In [107]:
df_simulations=np.zeros((YEARS_OF_SIMULATION,NUMBER_OF_SIMULATIONS))
df_simulations[0,:]=STARTING_CAPITAL
for x in tqdm(range(0,NUMBER_OF_SIMULATIONS)):
for i in range(1,YEARS_OF_SIMULATION):
annual_change=1
sample=random.sample(list(df.iloc[:]), Market_Days)
for k in sample:
annual_change=annual_change*(1+k)
df_simulations[i,x]=annual_change*df_simulations[i-1,x]
df_simulations= pd.DataFrame(df_simulations)
df_simulations_1= pd.DataFrame(df_simulations)
100%|██████████| 1000/1000 [00:33<00:00, 29.59it/s]
In [108]:
df_simulations_1
Out[108]:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | ... | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 |
| 1 | 1.134413e+04 | 1.247260e+04 | 1.334698e+04 | 9.367457e+03 | 1.036635e+04 | 1.250583e+04 | 9.191819e+03 | 1.030309e+04 | 8.987786e+03 | 9.288567e+03 | ... | 1.260585e+04 | 1.429908e+04 | 9.248619e+03 | 1.029220e+04 | 1.156244e+04 | 1.424779e+04 | 1.416758e+04 | 1.143433e+04 | 1.157058e+04 | 1.074109e+04 |
| 2 | 1.561928e+04 | 1.422493e+04 | 1.201346e+04 | 9.479533e+03 | 1.263824e+04 | 1.401505e+04 | 8.169493e+03 | 9.422684e+03 | 1.084129e+04 | 1.037433e+04 | ... | 1.457693e+04 | 1.839961e+04 | 1.360916e+04 | 1.334508e+04 | 1.183286e+04 | 1.993063e+04 | 1.328159e+04 | 1.105435e+04 | 1.355561e+04 | 1.394270e+04 |
| 3 | 1.380168e+04 | 1.531886e+04 | 1.414182e+04 | 1.097514e+04 | 1.576677e+04 | 1.645312e+04 | 1.002836e+04 | 1.164417e+04 | 1.109718e+04 | 1.190200e+04 | ... | 1.486444e+04 | 2.435777e+04 | 1.310376e+04 | 1.975421e+04 | 1.508570e+04 | 2.196314e+04 | 1.814657e+04 | 1.202445e+04 | 1.387370e+04 | 1.563897e+04 |
| 4 | 1.821995e+04 | 1.926214e+04 | 1.435740e+04 | 1.240471e+04 | 1.767177e+04 | 1.826375e+04 | 1.015524e+04 | 1.382388e+04 | 1.022149e+04 | 1.834370e+04 | ... | 1.818406e+04 | 2.361711e+04 | 1.519243e+04 | 2.994259e+04 | 2.008104e+04 | 2.609124e+04 | 1.872829e+04 | 1.199868e+04 | 1.378726e+04 | 1.540732e+04 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 96 | 1.856935e+08 | 1.650772e+08 | 3.058800e+08 | 1.796295e+09 | 7.560132e+08 | 3.698129e+08 | 3.487465e+08 | 8.629930e+08 | 5.583347e+07 | 1.855095e+08 | ... | 3.860443e+08 | 3.665524e+08 | 6.823822e+07 | 2.842071e+08 | 2.292527e+08 | 7.984285e+08 | 1.292156e+09 | 1.536690e+08 | 1.361641e+08 | 3.726219e+08 |
| 97 | 1.640858e+08 | 1.606045e+08 | 4.756060e+08 | 1.925638e+09 | 8.413814e+08 | 4.145991e+08 | 4.595609e+08 | 1.053684e+09 | 4.737342e+07 | 2.048719e+08 | ... | 4.112201e+08 | 4.121135e+08 | 9.131809e+07 | 3.342893e+08 | 2.377706e+08 | 7.763757e+08 | 1.681341e+09 | 1.965473e+08 | 1.179882e+08 | 3.972129e+08 |
| 98 | 2.129941e+08 | 1.550399e+08 | 5.752222e+08 | 1.861128e+09 | 1.020126e+09 | 5.220231e+08 | 5.747524e+08 | 1.153959e+09 | 4.699919e+07 | 2.268883e+08 | ... | 3.988091e+08 | 5.010547e+08 | 8.169651e+07 | 3.781270e+08 | 2.831714e+08 | 8.216336e+08 | 1.813164e+09 | 1.858420e+08 | 1.123322e+08 | 4.235876e+08 |
| 99 | 1.921964e+08 | 1.798258e+08 | 5.274156e+08 | 1.479774e+09 | 8.834827e+08 | 6.180547e+08 | 7.930645e+08 | 1.372137e+09 | 6.035718e+07 | 1.955386e+08 | ... | 3.571432e+08 | 6.424891e+08 | 1.240590e+08 | 4.121541e+08 | 3.759798e+08 | 9.680444e+08 | 2.229917e+09 | 2.185181e+08 | 1.123022e+08 | 4.264346e+08 |
| 100 | 1.845068e+08 | 1.867363e+08 | 7.564931e+08 | 1.388570e+09 | 8.890798e+08 | 6.780388e+08 | 8.545328e+08 | 1.462276e+09 | 5.588757e+07 | 2.066188e+08 | ... | 3.397576e+08 | 8.278420e+08 | 1.265184e+08 | 4.421544e+08 | 4.205972e+08 | 1.244072e+09 | 2.587593e+09 | 2.252467e+08 | 1.647732e+08 | 4.196487e+08 |
101 rows × 1000 columns
In [109]:
df_simulations=df_simulations_1
df_simulations.iloc[YEARS_OF_SIMULATION-1]
Out[109]:
0 1.845068e+08
1 1.867363e+08
2 7.564931e+08
3 1.388570e+09
4 8.890798e+08
...
995 1.244072e+09
996 2.587593e+09
997 2.252467e+08
998 1.647732e+08
999 4.196487e+08
Name: 100, Length: 1000, dtype: float64
In [110]:
quantile=df_simulations.iloc[YEARS_OF_SIMULATION-1].quantile([0.1,0.9])
quantile=list(quantile)
print(quantile)
df_simulations_purged=df_simulations[df_simulations.columns[ df_simulations.max() < quantile[1]]]
df_simulations_purged=df_simulations_purged[df_simulations_purged.columns[ df_simulations_purged.max() > quantile[0]]]
[68717480.23348887, 2806056474.4908504]
In [111]:
df_simulations_purged.plot(figsize=(16,8), title=f"Simulation of {NUMBER_OF_SIMULATIONS} portfolios", legend=False)
Out[111]:
<Axes: title={'center': 'Simulation of 1000 portfolios'}>
In [112]:
df_simulations_purged.iloc[YEARS_OF_SIMULATION-1].plot.density(figsize=(16,8),fontsize=14, xlim=(-100000,900000))
Out[112]:
<Axes: ylabel='Density'>
In [113]:
top_25 =[]
low_25 =[]
median=[]
for i in range(0,YEARS_OF_SIMULATION):
top_25.append(df_simulations.iloc[i].quantile(0.75))
low_25.append(df_simulations.iloc[i].quantile(0.25))
median.append(df_simulations.iloc[i].median())
columns=["top 25%","median","bottom 25%"]
df_statistics=pd.DataFrame(list(zip(top_25,median,low_25)),columns=columns)
df_statistics
Out[113]:
| top 25% | median | bottom 25% | |
|---|---|---|---|
| 0 | 1.000000e+04 | 1.000000e+04 | 1.000000e+04 |
| 1 | 1.244826e+04 | 1.121347e+04 | 1.012236e+04 |
| 2 | 1.447373e+04 | 1.264050e+04 | 1.092104e+04 |
| 3 | 1.660257e+04 | 1.401379e+04 | 1.175836e+04 |
| 4 | 1.906862e+04 | 1.555112e+04 | 1.256501e+04 |
| ... | ... | ... | ... |
| 96 | 7.562281e+08 | 2.916158e+08 | 1.051887e+08 |
| 97 | 8.523207e+08 | 3.291893e+08 | 1.131020e+08 |
| 98 | 9.692804e+08 | 3.515798e+08 | 1.279347e+08 |
| 99 | 1.129290e+09 | 3.885100e+08 | 1.380323e+08 |
| 100 | 1.244676e+09 | 4.321860e+08 | 1.597549e+08 |
101 rows × 3 columns
In [ ]:
#ax= df_statistics.plot(legend=None,logy=False,fontsize=20,figsize=(25,15),linewidth=4,color="black",title=f"Simulation of {NUMBER_OF_SIMULATIONS} portfolios")
pd.set_option('plotting.backend', 'plotly')
fig = df_statistics.plot(width=1600, height=800,title=f"Simulation of {NUMBER_OF_SIMULATIONS} portfolios",labels= {"index": "Years to Maturity", "value":"Total Capital"} ,template='plotly_dark')
fig.add_trace(go.Scatter(x=list(range(0,YEARS_OF_SIMULATION)),y=np.array(top_25),fill='tonexty',mode='lines', line_color='blue' , fillcolor ="red", showlegend=False, hoverinfo="skip"))
fig.add_trace(go.Scatter(x=list(range(0,YEARS_OF_SIMULATION)),y=np.array(median),fill='tonexty',mode='lines', line_color='orange', fillcolor="green", showlegend=False, hoverinfo="skip"))
In [ ]:
ls_simulations_at_profit=[]
for i in range(YEARS_OF_SIMULATION):
c=len([1 for i in list(df_simulations.iloc[i])if i > STARTING_CAPITAL])
ls_simulations_at_profit.append(c/NUMBER_OF_SIMULATIONS*100)
pd.set_option('plotting.backend', 'plotly')
df_simulations_at_profit = pd.DataFrame(ls_simulations_at_profit,columns=["Profit %"])
df_simulations_at_profit.plot(title="Minimum investment horizon", labels= {"index": "Period length in years", "value":"Chance to be in profit"},template='plotly_dark')
In [ ]:
In [ ]:
In [ ]:
TICKER="^GSPC"
In [ ]:
df=yf.download(TICKER)["Adj Close"].pct_change(1).dropna()
df_simulations = np.zeros((YEARS_OF_SIMULATION, NUMBER_OF_SIMULATIONS))
df_simulations[0, :] = STARTING_CAPITAL
for x in tqdm(range(0,NUMBER_OF_SIMULATIONS)):
for i in range(1,YEARS_OF_SIMULATION):
annual_change=1
sample=random.sample(list(df.iloc[:]), Market_Days)
for k in sample:
annual_change=annual_change*(1+k)
df_simulations[i,x]=annual_change*df_simulations[i-1,x]
In [ ]:
df_simulations = pd.DataFrame(df_simulations)
df_simulations_1 = pd.DataFrame(df_simulations)
df_simulations = df_simulations_1
df_simulations.iloc[YEARS_OF_SIMULATION - 1]
quantile = df_simulations.iloc[YEARS_OF_SIMULATION - 1].quantile([0.1, 0.9])
quantile = list(quantile)
df_simulations_purged = df_simulations[df_simulations.columns[df_simulations.max() < quantile[1]]]
df_simulations_purged = df_simulations_purged[df_simulations_purged.columns[df_simulations_purged.max() > quantile[0]]]
top_25 =[]
low_25 =[]
median=[]
for i in range(0,YEARS_OF_SIMULATION):
top_25.append(df_simulations.iloc[i].quantile(0.75))
low_25.append(df_simulations.iloc[i].quantile(0.25))
median.append(df_simulations.iloc[i].median())
columns=["top 25%","median","bottom 25%"]
df_statistics=pd.DataFrame(list(zip(top_25,median,low_25)),columns=columns)
import plotly.io as pio
fig = df_statistics.plot(width=1600, height=800,title=f"Simulation of {NUMBER_OF_SIMULATIONS} portfolios",labels= {"index": "Years to Maturity", "value":"Total Capital"} , template='plotly_dark')
fig.add_trace(go.Scatter(x=list(range(0,YEARS_OF_SIMULATION)),y=np.array(top_25),fill='tonexty',mode='lines', line_color='blue' , fillcolor ="red", showlegend=False, hoverinfo="skip"))
fig.add_trace(go.Scatter(x=list(range(0,YEARS_OF_SIMULATION)),y=np.array(median),fill='tonexty',mode='lines', line_color='orange', fillcolor="green", showlegend=False, hoverinfo="skip"))
In [ ]:
ls_simulations_at_profit = []
for i in range(YEARS_OF_SIMULATION):
c = len([1 for i in list(df_simulations.iloc[i]) if i > STARTING_CAPITAL])
ls_simulations_at_profit.append(c / NUMBER_OF_SIMULATIONS * 100)
pd.set_option('plotting.backend', 'plotly')
df_simulations_at_profit = pd.DataFrame(ls_simulations_at_profit, columns=["Profit %"])
df_simulations_at_profit.plot(title="Minimum investment horizon",
labels={"index": "Period length in years", "value": "Chance to be in profit"}, template='plotly_dark')
In [ ]:
In [ ]:
!jupyter nbconvert --to html Portfolio1.ipynb --HTMLExporter.theme=dark
In [ ]: